/*---------------------------------------------------------------------
 * File name: hal_flash.c
 *
 * Copyright (c) <2020-2022>, <ChenLong>
 *
 * All rights reserved.
 *
 * Author: ChenLong
 * Email: worldlong@foxmail.com
 *--------------------------------------------------------------------*/
#include "gd32f30x.h"
#include "hal_flash.h"
/*
*/
void HAL_Flash::unlock()
{  
  fmc_unlock(); 
}
/*
*/
void HAL_Flash::lock()
{  
  fmc_lock(); 
}
/*
*/
bool HAL_Flash::erase(uint32_t page_addr)
{  
  /* clear all pending flags */
  fmc_flag_clear(FMC_FLAG_BANK0_END);
  fmc_flag_clear(FMC_FLAG_BANK0_WPERR);
  fmc_flag_clear(FMC_FLAG_BANK0_PGERR);

  /* erase the flash pages */
  if(fmc_page_erase(page_addr) != FMC_READY) {
    return false;
  }
  
  return true;
}
/*
*/
int HAL_Flash::write(uint32_t addr, uint32_t *data, int num)
{  
  fmc_flag_clear(FMC_FLAG_BANK0_END);
  fmc_flag_clear(FMC_FLAG_BANK0_WPERR);
  fmc_flag_clear(FMC_FLAG_BANK0_PGERR);
    
  /* program flash */
  for(int i = 0; i<num; i++) {
    if(fmc_word_program(addr + i*4, data[i]) != FMC_READY) {
      return i;
    }
    fmc_flag_clear(FMC_FLAG_BANK0_END);
    fmc_flag_clear(FMC_FLAG_BANK0_WPERR);
    fmc_flag_clear(FMC_FLAG_BANK0_PGERR);
  }

  return num;
}

/*
read
*/
int HAL_Flash::read(uint32_t addr, uint32_t *data, int num)
{
  /* must 4Bytes align */
  if((addr%4) != 0) {
    return 0;
  }
  
  for(int i=0; i<num; i++) {
    data[i] = *(__IO uint32_t*)(addr + i*4);
  }

  return num;
}






